home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK2.toast / Development Kits (Disc 2) / QuickDraw GX / Programming Stuff / Sample Code / Graphics Samples / rotating rects ƒ / graphics shell.c next >
Encoding:
C/C++ Source or Header  |  1996-04-14  |  12.0 KB  |  370 lines  |  [TEXT/KAHL]

  1. /**  
  2.  --        graphics shell.c
  3.  --
  4.  --        This file is a shell that can be used to build QuickDraw GX graphics applications.  
  5.  --        It contains all of the required calls to use the "new" QuickDraw GX routines and 
  6.  --        QuickDraw (i.e. windows) together. It will put up one window. You "quit" 
  7.  --        the application by clicking in the close box.  This shell does not use a menu.
  8.  --        
  9.  --     The application is expected to supply the following functions which are called
  10.  --        by this shell:
  11.  --
  12.  --            void DoInitialization(WindowPtr);
  13.  --            void DoDraw(WindowPtr);
  14.  --            void DoDispose(WindowPtr);
  15.  --            void DoClick(gxPoint, WindowPtr);
  16.  --            void DoIdle(WindowPtr);
  17.  --
  18.  --
  19.  --     Change History:
  20.  --
  21.  --        4/96 -    Updated #includes to support changed GX Library names.
  22.  --                        Updated the copyright date.        BOB
  23.  --
  24.  --        4/94    - Added the gxPoint as a parameter to the DoClick( gxPoint mouseLoc, WindowPtr myWindow ) 
  25.  --                  function to support hit testing.  PLA
  26.  --
  27.  --        3/94    - Removed the following varaibles: gDebugging & gGiveMeValidation see the comments
  28.  --                  for details (below). 
  29.  --
  30.  --                - Added a Gestalt check to see if GX has been installed. Added extensive error 
  31.  --                  checking to make sure the GX graphics client has been created and the GX heap
  32.  --                  correctly allocated. This shell will shut down at start-up and alert the user
  33.  --                  to the problem and bail if: GX is not installed, we cannot create the graphics
  34.  --                  client, or create a GX heap.  PLA
  35.  --
  36.  --        12/93    Updated the comment above the GXNewGraphicsCLient call to reflect the new fucntionality
  37.  --                of this call in ß3. I also removed the work around with GXConvertQDPoint (..) where
  38.  --                the call would not survive validation under ß2. Under ß3 the call suceeds when validation
  39.  --                is set.   PLA
  40.  --
  41.  --        8/93    - Updated this file to run with the QD GX ß2 "GX-ified" interfaces
  42.  --                - worked around a problem with GXConvertQDPoint (..) see the comments within
  43.  --                  the GetWindowBoundsShape (..) call for details (below).  PLA
  44.  --
  45.  --        6/92    Made the following variables global: gDebugging, gGiveMeValidation,gGraphicsHeapSize. 
  46.  --                See the comments for detail in this file.  PLA
  47.  --
  48.  --        6/91    Updated the shell to reflect the changes in "Graphics" v1.0d21.2.  PLA
  49.  --
  50.  --        3/90    New  - PLA
  51.  --
  52.  --
  53.  --        © Apple Computer, Inc. 1990 - 1996  All rights reserved
  54.  --                                
  55. **/
  56.  
  57.  
  58. #include <Desk.h>
  59. #include <Events.h>
  60. #include <Fonts.h>
  61. #include <Windows.h>
  62. #include <Memory.h>
  63. #include <ToolUtils.h>
  64. #include <Quickdraw.h>
  65. #include <GestaltEqu.h>
  66.  
  67. #include <GXEnvironment.h>
  68. #include <GXGraphics.h>
  69. #include "GraphicsLibraries.h"
  70. #include <GXErrors.h>
  71.  
  72. #include "graphics shell.h"
  73.  
  74. #define    kOSEvent                        app4Evt    // event used by MultiFinder
  75. #define    kSuspendResumeMessage            1        // high byte of suspend/resume event message
  76. #define    kResumeMask                        1        // bit of message field for resume vs. suspend
  77.  
  78.  
  79. WindowPtr         gWindow, whichWindow;
  80.  
  81. EventRecord        gtheEvent;
  82. gxShape         gWindowBoundsShape;
  83. gxViewPort        gTheWindowsViewPort;    
  84.  
  85. /**------ Function Prototypes -----**/
  86. void main(void);
  87. gxShape GetWindowBoundsShape(void);
  88. Boolean EventLoop(void);
  89. void SetUpGXDebuggingWorld (Boolean GXDebuggingInstalled);
  90.  
  91. /*------ main -----------------------------------------------------------------------------------------*/
  92.  
  93. void main()
  94. {        
  95.     CursHandle            theCurs; 
  96.     long                theFeature;
  97.     Boolean                debuggingInitInstalled = false;
  98.     
  99.     //
  100.     //   Generic heap initialization.
  101.     //
  102.     MaxApplZone(); 
  103.     MoreMasters(); MoreMasters(); MoreMasters(); 
  104.     MoreMasters(); MoreMasters(); MoreMasters(); 
  105.  
  106.     //
  107.     //   Initialize the toolbox 
  108.     //
  109.      InitGraf(&qd.thePort);
  110.     InitFonts();
  111.     InitWindows();
  112.     InitCursor();
  113.  
  114.     theCurs = GetCursor(watchCursor);
  115.     SetCursor(*theCurs);
  116.  
  117.     //
  118.     //    Check to see if QuickDraw GX is installed. If not, alert the user...
  119.     //
  120.     if ( (Gestalt(gestaltGraphicsVersion, &theFeature) == noErr) )
  121.     {
  122.         gxGraphicsClient     newClient;
  123.         
  124.         //
  125.         //    The GX gestaltGraphicsAttr Gestalt attribute can be used to determine if:
  126.         //    the graphics piece of GX has been loaded, the GX debugging init is installed, or
  127.         //    your are running the PowerPC version. 
  128.         //
  129.         //    In our case, we only need to know if the debugging init was installed. If it is,
  130.         //    we will enable the GX validation and notice handling features.We define 
  131.         //    debuggingInitInstalled as true to enable GX validation and notice handler
  132.         //  within the SetUpGXDebuggingWorld function.
  133.         //
  134.         if ( (Gestalt(gestaltGraphicsAttr, &theFeature) == noErr) )
  135.           if ( (theFeature & gestaltGraphicsIsDebugging) == gestaltGraphicsIsDebugging ) 
  136.              debuggingInitInstalled = true;
  137.     
  138.  
  139.         newClient = GXNewGraphicsClient(nil, gGraphicsHeapSize * 1024, 0L);
  140.  
  141.         //
  142.         //    After we attempted to create the graphics client, we need to determine if the call
  143.         //  succeeded. If the call did not (as in the case for all GX functions), "newClient" will
  144.         //    be nil. If it is, we alert the user to the problem. Otherwise, we will attempted to 
  145.         //    allocate the GX heap below...
  146.         //        
  147.         if ( newClient ) 
  148.         {
  149.             //
  150.             //    Initialize the new graphics environment and create the GX heap.
  151.             //
  152.             GXEnterGraphics();
  153.  
  154.             //
  155.             //    Calling GXEnterGraphics allocates the memory within the GX heap. The only reason the
  156.             //  call would not succeed is if there is not enough memory. In this case, the graphics 
  157.             //  error which will be posted is -27999 (out of memory). At this point, we have not 
  158.             //    installed an error handler, so we check for the error number corresponding to the 
  159.             //  out of memory error.
  160.             //
  161.             if ( GXGetGraphicsError( nil ) != -27999 ) 
  162.             {
  163.                 SetUpGXDebuggingWorld (debuggingInitInstalled);
  164.  
  165.                 //
  166.                 //    Create a window and attach a GX viewPort to it. By attaching the viewPort to 
  167.                 //    the window will make sure that when a user moves or resizes the window all of
  168.                 //    the GX drawing will occur within window. 
  169.                 //
  170.                 //    By the way, you cannot directly manipulate the parent viewPort attached to the
  171.                 //    window, you will recieve a graphics error. This viewPort can only be manipulated
  172.                 //  by the GX system. If you want to manipulate a viewPort attached to a window, it
  173.                 //     _must_ be a child viewPort attached to the the parent viewPort attached to the
  174.                 //    window.
  175.                 //
  176.                 gWindow = NewWindow(nil, &gWindowQDRect, gWindowTitle, true, noGrowDocProc,
  177.                                    (WindowPtr)-1L, true, 0L);
  178.                                    
  179.                 gTheWindowsViewPort = GXNewWindowViewPort(gWindow);
  180.  
  181.                 GXIgnoreGraphicsNotice(transform_already_set);
  182.                 SetDefaultViewPort(gTheWindowsViewPort);
  183.                 GXPopGraphicsNotice();
  184.  
  185.                 //
  186.                 //  Get the global bounds of the window.
  187.                 //
  188.                 gWindowBoundsShape = GetWindowBoundsShape();
  189.  
  190.                  //
  191.                  //    Create the GX shapes we are going to draw to the window. 
  192.                  //
  193.                  DoInitialization(gWindow);
  194.  
  195.                 SetCursor(&qd.arrow);  
  196.     
  197.                 while (EventLoop())
  198.                       DoIdle(gWindow);   // loop until the window is closed
  199.  
  200.                 DoDispose(gWindow);
  201.     
  202.                 GXExitGraphics();     // Deallocate all of the default structures
  203.                 GXDisposeGraphicsClient(newClient);
  204.         
  205.             } else {
  206.                 //
  207.                 //     Since, we can not allocate the requested size for our GX heap, we need to throw
  208.                 //  away the client we created and alert the user that there is not enough memory to
  209.                 //  continue.
  210.                 //
  211.                 //    However, you could try to create a smaller GX heap. If you decide to try to create
  212.                 //     a smaller GX heap which would meet the needs of your application, you need to 
  213.                 //     dispose of the client you had originally created. Why? The original client 
  214.                 //    contains the GX heap size requested, which was too big, therefore you need to 
  215.                 //    dispose of it and create a client requesting a smaller size and call GXEnterGraphics
  216.                 //     and check for an error. 
  217.                 //
  218.                 GXDisposeGraphicsClient( newClient );
  219.                 DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");
  220.             }
  221.           }
  222.  
  223.     } else DebugStr ("\p Unfortunately, you have not installed QuickDraw GX, I can't run without GX...");
  224.     
  225. }
  226.  
  227.  
  228.  
  229. /*------ SetUpGXDebuggingWorld ------------------------------------------------------------------------*/
  230. //
  231. //    This function enables the GX error handling capabilities and validation routines. The validation
  232. //    routines are only enabled, if the user has installed the QuickDraw GX debugging init. These routines
  233. //    are not available with the non-debugging init. Calling them when they are not installed will not 
  234. //    cause any problems, but it will cause unnecessary work to be done by your application and the GX 
  235. //    dispatcher.
  236. //
  237. void SetUpGXDebuggingWorld (Boolean debuggingInitInstalled)
  238. {
  239.       // 
  240.     //    We set-up GX validation, if the user has installed the "GXGraphics (debug)" init (formerly
  241.     //    named "aSecretGraphics.debug). This validation setting is the reccommended setting while
  242.     //    you are developing your GX application. As you increase the amount of validation, the drawing
  243.     //    speed will SLOW down due to all of the internal checking. 
  244.     //
  245.     //    For additional details regarding the various levels of validation, please see the
  246.     //    QuickDraw GX : Environment & Utilities book.
  247.     //
  248.     if ( debuggingInitInstalled ) GXSetValidation(gxPublicValidation + gxTypeValidation); 
  249.  
  250.     // 
  251.     //    Calling SetGraphicsLibraryErrors will install a GX error and warning handler. This
  252.     //    call is provided by the QuickDraw GX "graphics debugging library". Any time a GX error
  253.     //    or warning is generated, it will be posted to Macsbug.
  254.     //
  255.     SetGraphicsLibraryErrors ();
  256.         
  257.     //
  258.     //    If the user has installed the GX debugging version, we install a notice handler. Why? The
  259.     //    GX notice handling capabilities are only available with the debugging version.
  260.     //
  261.     if ( debuggingInitInstalled ) SetGraphicsLibraryNotices();
  262. }
  263.  
  264.  
  265.  
  266. /*------ GetWindowBoundsShape -------------------------------------------------------------------------*/
  267.  
  268. gxShape  GetWindowBoundsShape()
  269. {
  270.     Rect                theRect;
  271.     Point                QDtopLeft;
  272.     Point                QDbotRight;
  273.     gxPoint                QDGXtopLeft;
  274.     gxPoint                QDGXbotRight;
  275.     gxRectangle            theQDGXRect;
  276.     
  277.     //
  278.     // The QuickDraw rect and points which represent the portRect of the window. 
  279.     //
  280.     theRect = gWindow->portRect;
  281.     QDtopLeft.h = theRect.left;
  282.     QDtopLeft.v = theRect.top;
  283.     QDbotRight.h = theRect.right;
  284.     QDbotRight.v = theRect.bottom;
  285.      
  286.     //
  287.     //  Convert the global Quickdraw coordinates to local fixed coordinates.
  288.     //
  289.     GXConvertQDPoint(&QDtopLeft, 0, &QDGXtopLeft);
  290.     GXConvertQDPoint(&QDbotRight, 0, &QDGXbotRight);
  291.  
  292.     //
  293.     //  Setup the dimensions for "gWindowBoundsShape"
  294.     //
  295.     theQDGXRect.top = QDGXtopLeft.y;
  296.     theQDGXRect.left = QDGXtopLeft.x;
  297.     theQDGXRect.bottom = QDGXbotRight.y;
  298.     theQDGXRect.right = QDGXbotRight.x;
  299.     
  300.     return (GXNewRectangle(&theQDGXRect));
  301. }
  302.  
  303.  
  304.  
  305. /*------ EventLoop ------------------------------------------------------------------------------------*/
  306.  
  307. Boolean EventLoop()
  308. {
  309.     static long     sleep = 0;
  310.  
  311.     WaitNextEvent(everyEvent, >heEvent, sleep, nil);
  312.          
  313.     switch(gtheEvent.what)
  314.     {                    
  315.         case updateEvt:
  316.                 BeginUpdate((WindowPtr) gtheEvent.message);
  317.                 SetPort(gWindow);
  318.                 DoDraw(gWindow);
  319.                 EndUpdate((WindowPtr) gtheEvent.message);
  320.         break;
  321.         
  322.         case mouseDown:
  323.             switch (FindWindow(gtheEvent.where, &whichWindow)) {
  324.                 case inSysWindow:
  325.                     SystemClick(>heEvent, whichWindow);
  326.                 break;
  327.                         
  328.                 case inDrag:
  329.                     DragWindow(whichWindow, gtheEvent.where, &qd.screenBits.bounds);
  330.                 break;
  331.  
  332.                 case inGoAway:
  333.                     if (TrackGoAway(whichWindow, gtheEvent.where))
  334.                         return false;
  335.                 break;
  336.                 
  337.                 case inContent:
  338.                     if (whichWindow != FrontWindow())
  339.                          SelectWindow(whichWindow);
  340.                      else
  341.                      {
  342.                          gxPoint        mouseLoc;
  343.                          Point        currMouseLoc;
  344.                          
  345.                          currMouseLoc.h = gtheEvent.where.h;
  346.                          currMouseLoc.v = gtheEvent.where.v;
  347.                          
  348.                         GXConvertQDPoint(&currMouseLoc, gTheWindowsViewPort, &mouseLoc);
  349.  
  350.                          DoClick(mouseLoc, gWindow);
  351.                      }
  352.                 break;
  353.  
  354.             }
  355.             
  356.         case kOSEvent:
  357.             switch ((unsigned long) gtheEvent.message >> 24) {    //  high byte of message
  358.                  case kSuspendResumeMessage:            //  suspend/resume is also an activate/deactivate
  359.                     if ((gtheEvent.message & kResumeMask) == 0)
  360.                        sleep = 80;                    // we are headed to the background, so slow down...  
  361.                     else
  362.                        sleep = 0;                    // we are headed to the foreground, so speed up... 
  363.                 break;
  364.             }
  365.                 break;
  366.     }
  367.     return true;
  368. }
  369.  
  370.